import castPath from './.internal/castPath.js';
import isArguments from './isArguments.js';
import isIndex from './.internal/isIndex.js';
import isLength from './isLength.js';
import toKey from './.internal/toKey.js';
import deepClone from "./.internal/deepClone.js"

/** Used to check objects for own properties. */
const hasOwnProperty = Object.prototype.hasOwnProperty;

/**
 * Checks if `path` is a direct property of `object`.
 *
 * @since 5.0.0
 * @category Object
 * @param {Object} object The object to query.
 * @param {Array|string} path The path to check.
 * @returns {boolean} Returns `true` if `path` exists, else `false`.
 * @see has, hasIn, hasPathIn
 * @example
 *
 * const object = { 'a': { 'b': 2 } }
 * const other = create({ 'a': create({ 'b': 2 }) })
 *
 * hasPath(object, 'a.b')
 * // => true
 *
 * hasPath(object, ['a', 'b'])
 * // => true
 */
function hasPath(object, path) {
	let _obj = deepClone(object);
	
	path = castPath(path, _obj);

	let index = -1;
	let { length } = path;
	let result = false;
	let key;

	while (++index < length) {
		key = toKey(path[index]);
		if (!(result = _obj != null && hasOwnProperty.call(_obj, key))) {
			break;
		}
		_obj = _obj[key];
	}
	if (result || ++index !== length) {
		return result;
	}
	length = object == null ? 0 : _obj.length;

	return (
		!!length &&
		isLength(length) &&
		isIndex(key, length) &&
		(Array.isArray(_obj) || isArguments(_obj))
	);
}

export default hasPath;